<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------

namespace app\mill\model;

use think\Model;
use think\helper\Hash;
use think\Db;

/**
 * T+Cloud 畅捷通
 */
class TCloud extends Model
{
    const REQ_GET = 1;
    const REQ_POST = 2;
    const NOT_TOKEN = 'NOT_TOKEN';
    //配置  正式
    public static $config = [
        'url'               =>  'https://openapi.chanjet.com',//正式地址
        'aesKey'            =>  '7FCBBCEC79B8305C',//AES解密用的秘钥

        'appKey'            =>  'pLBnTnd8',//appKey 正式
        'appSecret'         =>  '7FCBBCEC79B8305C7DB8DCE34BF0E156',//appSecret 正式
        'certificate'       =>  'OXYwHSWAc22UPHxfIUM0Sfqjda3xNfKjbkMJ5d41oUHmSEemKhPKTkQ2Pl5hs5OoIWMnJPdn2/Ic6stVHMrGlKuh/DxDywljHbo9v0hwkP/m1EdVEMg37semSUTLNJr+wM8r5LX3Quk3UfNin70LZZLbWamUIF3kqR3JvmhVah0iVzjYDoeDexJlKgyPf6oL',//加密证书 正式

        /* 'appKey'            =>  'D0wjyRZn',//appKey 测试
         'appSecret'         =>  'EE6B6503AA91095856F5A9A5739B1515',//appSecret 测试
         'certificate'       =>  'OXYwHSWAc22UPHxfIUM0Sd7mdutZRV0N3XcoNv6H3SSkMRgyfZ/7CgzkzsdYm20wKm2WtycuzJAbsHwpP5F5bKuh/DxDywljHbo9v0hwkP/m1EdVEMg37semSUTLNJr+wM8r5LX3Quk3UfNin70LZZsWmXo4TaIpnmbuSCQXiAUiVzjYDoeDexJlKgyPf6oL',//加密证书 测试*/

        'file'              =>  [//文件目录
            'TOKEN'         =>  'uploads/TCloud/token.log',//token
            'APP_TICKET'    =>  'uploads/TCloud/ticket.log',//临时授权码
        ]
    ];
    //token
    public static $token = '';

    /**
     * 执行CURL请求
     * @author: xialei<xialeistudio@gmail.com>
     * @param $url
     * @param array $params
     * @param array $header
     * @param int $method
     * @param bool $encode
     * @return mixed
     */
    public static function async($url, $params = array(), $header = [], $method = self::REQ_POST, $encode = true)
    {
        $config = self::$config;
        $headers = [
            "appKey:{$config['appKey']}",
            "appSecret:{$config['appSecret']}",
        ];
        //是否添加token
        if(!in_array(self::NOT_TOKEN,$header)){
            $token = self::getToken();
            if(is_array($token))return json_encode($token,true);
            $headers[] = "openToken:{$token}";
        }

        $ch = curl_init();
        if ($method == self::REQ_GET)
        {
            $url = $url . '?' . http_build_query($params);
            $url = $encode ? $url : urldecode($url);
            curl_setopt($ch, CURLOPT_URL, $url);
        }
        else
        {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));

            $headers[] = 'Content-Type:application/json';
        }
        if(!empty($header))$headers = array_merge($headers,$header);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        //curl_setopt($ch, CURLOPT_REFERER, 'referer');
        //curl_setopt($ch, CURLOPT_USERAGENT, '');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $resp = curl_exec($ch);
        curl_close($ch);
        return $resp;
    }

    //获取文件内容，或记录内容
    public static function fileValue($file = '',$val = '',$time = ''){
        if(empty($file))return ['data'=>''];
        $i = strrpos($file,'/');
        if(empty($time))$time = time();
        if(!empty($i)){
            $filePath = mb_substr($file,0,$i);
            if(!is_readable($filePath)) {
                @mkdir($filePath,0777);
                @chmod($filePath,0777);
            }
        }
        if(!empty($val))
        {
            $set_val = json_encode(['data'=>$val,'time'=>$time]);
            $result = file_put_contents($file,$set_val);
            if(empty($result))return ['data'=>''];
            else return json_decode($set_val,true);
        }
        else
        {
            if(file_exists($file)) return json_decode(file_get_contents($file),true);
            return ['data'=>''];
        }
    }

    //获取临时授权码
    public static function appTicket($is_curl = true)
    {
        $config = self::$config;
        $api = $config['url']."/auth/appTicket/resend";

        $header = [self::NOT_TOKEN];
        if($is_curl){
            $resp = self::async($api,[],$header);
            $data = json_decode($resp, true);
        }
        else $data['code'] = 200;

        $data['appTicket'] = '';

        //AES回调解密
        //回调地址：http://xhy.lgb668.com/api.php/mill/tcloud/appTicketCallback
        if($data['code'] == 200){
            //延时0.13秒后获取回调内容，给T+平台一个请求回调的时间
            time_nanosleep(0,130000000);
            $data['appTicket'] = self::fileValue($config['file']['APP_TICKET'],'',0)['data'];
            //延时0.13秒后，有小概率还无法获取回调内容，此时进入延时循环，直到获取到为止
            //如果出现一直循环，最终超时，则T+平台的回调地址设置可能出问题了，或者文件权限不够
            if(empty($data['appTicket']))$data = self::appTicket(false);
            //获取到记录文件后，删除
            @unlink($config['file']['APP_TICKET']);
        }
        return $data;
    }

    //自建应用获取token
    public static function getToken()
    {
        $config = self::$config;
        $api = $config['url']."/v1/common/auth/selfBuiltApp/generateToken";

        $token = self::fileValue($config['file']['TOKEN']);
        if(!empty($token['time']) && $token['time'] > time() && !empty($token['data']))return $token['data'];

        $header = [self::NOT_TOKEN];
        //回调地址
        $appTicket = self::appTicket();
        $params = array(
            'appTicket' => $appTicket['appTicket'],//临时授权码
            'certificate' => $config['certificate'],//加密证书
        );

        $resp = self::async($api, $params, $header);
        $data = json_decode($resp, true);
        //保存token
        if(empty($data['error'])){
            $time = time() + $data['value']['expiresIn'];//有效时间
            $token = self::fileValue($config['file']['TOKEN'],$data['value']['accessToken'],$time);
            return $token['data'];
        }
        //返回地址信息 如果status!=0则信息错误
        return $data;
    }

    //项目查询
    public static function getProject($name = '',$code = '',$selectFields = 'ID,Code,Name,ProjectClass.Code')
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/Project/Query2";

        $params = [
            'param'                     =>  [
                'SelectFields'          =>  $selectFields
            ]
        ];
        if(!empty($name))$params['param']['Name'] = $name;
        if(!empty($code))$params['param']['Code'] = $code;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //项目创建
    public static function projectCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/Project/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['order_sn'],//编号
                'Name'                  =>  $data['order_sn'],//名称
                'ProjectClass'          =>  [
                    'Code'              =>  '01'//所属类别，项目分类编码 （去T+系统，来往单位那里查看）
                ],
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //员工查询
    public static function getPerson($name = '',$code = '',$selectFields = 'Code,Name,Department.Code')
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/person/Query";

        $params = [
            'dto'                       =>  [
                'SelectFields'          =>  $selectFields
            ]
        ];
        if(!empty($name))$params['dto']['Name'] = $name;
        if(!empty($code))$params['dto']['Code'] = $code;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //员工创建
    public static function personCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/person/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['sales_code'],//编号
                'Name'                  =>  $data['sales'],//名称
                'IsSalesMan'            =>  'true',//是否业务员
                'Department'            =>  [
                    'Code'              =>  '0401',//部门编码 0401：装饰销售（T+的部门编码，去销售订单那里查看）
                ],
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //来往单位查询
    public static function getPartner($name = '',$code = '',$selectFields = 'Code,Name,PartnerType.Code,PartnerClass.Code')
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/partner/Query";

        $params = [
            'param'                     =>  [
                'SelectFields'          =>  $selectFields
            ]
        ];
        if(!empty($name))$params['param']['Name'] = $name;
        if(!empty($code))$params['param']['Code'] = $code;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //来往单位创建
    public static function partnerCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/partner/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['company_code'],//编号
                'Name'                  =>  $data['company'],//名称
                'PartnerType'           =>  [
                    'Code'              =>  '01'//分类： 01 客户 00 供应商 02 客户/供应商 为空时，默认为客户
                ],
                'PartnerClass'          =>  [
                    'Code'              =>  '0101'//所属类别，往来单位分类编码 （去T+系统，来往单位那里查看）
                ],
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //存货查询
    public static function getInventory($name = '',$code = '',$selectFields = 'ID,Code,Name')
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/inventory/Query";

        $params = [
            'param'                     =>  [
                'SelectFields'          =>  $selectFields
            ]
        ];
        if(!empty($name))$params['param']['Name'] = $name;
        if(!empty($code))$params['param']['Code'] = $code;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //档案号创建
    public static function archivesCreate($code = '')
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/inventory/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $code,//编号
                'Name'                  =>  $code,//名称
                'Shorthand'             =>  $code,//助记码
                'Warehouse'             =>  [
                    'Code'              =>  '08',//默认仓库编码，（去T+系统，存货那里查看）
                    //'Name'              =>  '成品',//默认仓库名称，（去T+系统，存货那里查看）
                ],
                'InventoryClass'        =>  [
                    'Code'              =>  '07',//存货分类编号，（去T+系统，存货那里查看）
                    //'Name'              =>  '档案号',//存货分类名称，（去T+系统，存货那里查看）
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//计量单位
                ],
                'ValueType'             =>  [
                    'Code'              =>  '01'//计价方式 00：全月平均  01：移动平均  03：先进先出  04：个别计价
                ],

                'IsPurchase'            =>  'False',//存货属性：外购属性  取值："True","False"
                'IsSale'                =>  'False',//存货属性：销售属性  取值："True","False"
                'IsMadeSelf'            =>  'True',//存货属性：自制属性  取值："True","False"
                'IsMaterial'            =>  'True',//存货属性：生产耗用属性  取值："True","False"
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //面积表存货编码
    public static function getInvertoryCode($data = []){
        return $data['archives_sn'].$data['model_sn'];
    }
    //面积表存货批量创建
    public static function inventoryCreateBatch($list = [])
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/inventory/CreateBatch";

        $params['dtos'] = [];
        foreach ($list as $data){
            $dto = [
                'Code'                  =>  self::getInvertoryCode($data),//编号
                'Name'                  =>  $data['archives_sn'],//名称
                'Shorthand'             =>  $data['archives_sn'],//助记码
                'Specification'         =>  $data['model_sn'],//规格型号
                'InventoryDescript'     =>  $data['note'],//存货描述
                'InvSCost'              =>  $data['one_area'],//参考成本
                'LatestCost'            =>  $data['one_area'],//最新成本
                'AvagCost'              =>  $data['one_area'],//平均成本
                'InvUnitPriceDTOs'      =>  [//浮动换算率
                    [
                        'Unit'          =>  [
                            'Name'      =>  '件'//单位
                        ],
                        'rateOfExchange'=>  $data['one_area']//换算率
                    ]
                ],

                'Warehouse'             =>  [
                    'Code'              =>  '08',//默认仓库编码，（去T+系统，存货那里查看）
                    //'Name'              =>  '成品',//默认仓库名称，（去T+系统，存货那里查看）
                ],
                'InventoryClass'        =>  [
                    'Code'              =>  '06',//存货分类编号，（去T+系统，存货那里查看）
                    //'Name'              =>  '成品',//存货分类名称，（去T+系统，存货那里查看）
                ],
                'ValueType'             =>  [
                    'Code'              =>  '01'//计价方式 00：全月平均  01：移动平均  03：先进先出  04：个别计价
                ],
                'UnitType'              =>  [
                    'Code'              =>  '01'//计量单位类型 00：单计量  01：多计量
                ],

                'Unit'                  =>  [
                    'Name'              =>  '㎡'//计量单位
                ],
                'UnitGroup'             =>  [
                    'Name'              =>  '㎡件'//多计量单位组；如果是多计量单位的存货，该项必录
                ],
                'ChangeType'            =>  [
                    'Name'              =>  '0'//换算类型  0：固定  1：浮动
                ],
                'UnitByStock'           =>  [
                    'Name'              =>  '㎡'//库存常用单位
                ],
                'UnitByPurchase'        =>  [
                    'Name'              =>  '㎡'//采购常用单位
                ],
                'UnitBySale'            =>  [
                    'Name'              =>  '㎡'//销售常用单位
                ],
                'MainUnit'              =>  [
                    'Name'              =>  '件'//主计量
                ],
                'Unit1'                 =>  [
                    'Name'              =>  '件'//辅计量1
                ],

                'IsPurchase'            =>  'True',//存货属性：外购属性  取值："True","False"
                'IsSale'                =>  'True',//存货属性：销售属性  取值："True","False"
                'IsMadeSelf'            =>  'True',//存货属性：自制属性  取值："True","False"
                'IsMaterial'            =>  'True',//存货属性：生产耗用属性  取值："True","False"

                //'DynamicPropertyKeys'   =>  [],//自定义字段    ["priuserdefnvc1","priuserdefdecm1"]
                //'DynamicPropertyValues' =>  [],//自定义字段值  ["heihei",56]
            ];
            //自定义字段
            $DynamicProperty = [
                //priuserdefnvc：字符串格式
                'priuserdefnvc3'        =>  'page',//页码
                'priuserdefnvc4'        =>  'plank',//材质，板材
                'priuserdefnvc5'        =>  'model',//版型
                'priuserdefnvc6'        =>  'color',//颜色
                'priuserdefnvc9'        =>  'extra',//配件
                'priuserdefnvc10'       =>  'stiffener',//型材组装长度
                'priuserdefnvc11'       =>  'bend',//超长
                'priuserdefnvc12'       =>  'torque',//超宽

                //priuserdefdecm：数字格式
                'priuserdefdecm2'       =>  'long',//L，长
                'priuserdefdecm3'       =>  'high',//H，高
                'priuserdefdecm4'       =>  'thickness',//板厚
                'priuserdefdecm6'       =>  'weld',//焊接
                'priuserdefdecm7'       =>  'slot',//刨槽
                'priuserdefdecm8'       =>  'sort',//恒亚序号
            ];

            $DynamicPropertyKeys = [];
            $DynamicPropertyValues = [];
            foreach ($DynamicProperty as $k=>$v){
                $DynamicPropertyKeys[] = $k;
                if(strpos($k,'priuserdefdecm') !== false)$data[$v] = floatval($data[$v]);
                $DynamicPropertyValues[] = $data[$v];
            }
            $dto['DynamicPropertyKeys'] = $DynamicPropertyKeys;
            $dto['DynamicPropertyValues'] = $DynamicPropertyValues;

            $params['dtos'][] = $dto;
        }

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }
    //面积表存货修改
    public static function inventoryUpdate($data = [])
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/inventory/Update";

        $params['dto'] =  [
            'Code'                  =>  self::getInvertoryCode($data),//编号
            'Name'                  =>  $data['archives_sn'],//名称
            'Shorthand'             =>  $data['archives_sn'],//助记码
            'Specification'         =>  $data['model_sn'],//规格型号
            'InventoryDescript'     =>  $data['note'],//存货描述
            'InvSCost'              =>  $data['one_area'],//参考成本
            'LatestCost'            =>  $data['one_area'],//最新成本
            'AvagCost'              =>  $data['one_area'],//平均成本
            'InvUnitPriceDTOs'      =>  [//浮动换算率
                [
                    'Unit'          =>  [
                        'Name'      =>  '件'//单位
                    ],
                    'rateOfExchange'=>  $data['one_area']//换算率
                ]
            ],

            'Warehouse'             =>  [
                'Code'              =>  '08',//默认仓库编码，（去T+系统，存货那里查看）
                //'Name'              =>  '成品',//默认仓库名称，（去T+系统，存货那里查看）
            ],
            'InventoryClass'        =>  [
                'Code'              =>  '06',//存货分类编号，（去T+系统，存货那里查看）
                //'Name'              =>  '成品',//存货分类名称，（去T+系统，存货那里查看）
            ],
            'ValueType'             =>  [
                'Code'              =>  '01'//计价方式 00：全月平均  01：移动平均  03：先进先出  04：个别计价
            ],
            'UnitType'              =>  [
                'Code'              =>  '01'//计量单位类型 00：单计量  01：多计量
            ],

            'Unit'                  =>  [
                'Name'              =>  '㎡'//计量单位
            ],
            'UnitGroup'             =>  [
                'Name'              =>  '㎡件'//多计量单位组；如果是多计量单位的存货，该项必录
            ],
            'ChangeType'            =>  [
                'Name'              =>  '0'//换算类型  0：固定  1：浮动
            ],
            'UnitByStock'           =>  [
                'Name'              =>  '㎡'//库存常用单位
            ],
            'UnitByPurchase'        =>  [
                'Name'              =>  '㎡'//采购常用单位
            ],
            'UnitBySale'            =>  [
                'Name'              =>  '㎡'//销售常用单位
            ],
            'MainUnit'              =>  [
                'Name'              =>  '件'//主计量
            ],
            'Unit1'                 =>  [
                'Name'              =>  '件'//辅计量1
            ],

            'IsPurchase'            =>  'True',//存货属性：外购属性  取值："True","False"
            'IsSale'                =>  'True',//存货属性：销售属性  取值："True","False"
            'IsMadeSelf'            =>  'True',//存货属性：自制属性  取值："True","False"
            'IsMaterial'            =>  'True',//存货属性：生产耗用属性  取值："True","False"

            //'DynamicPropertyKeys'   =>  [],//自定义字段    ["priuserdefnvc1","priuserdefdecm1"]
            //'DynamicPropertyValues' =>  [],//自定义字段值  ["heihei",56]
        ];
        //自定义字段
        $DynamicProperty = [
            //priuserdefnvc：字符串格式
            'priuserdefnvc3'        =>  'page',//页码
            'priuserdefnvc4'        =>  'plank',//材质，板材
            'priuserdefnvc5'        =>  'model',//版型
            'priuserdefnvc6'        =>  'color',//颜色
            'priuserdefnvc9'        =>  'extra',//配件
            'priuserdefnvc10'       =>  'stiffener',//型材组装长度
            'priuserdefnvc11'       =>  'bend',//超长
            'priuserdefnvc12'       =>  'torque',//超宽

            //priuserdefdecm：数字格式
            'priuserdefdecm2'       =>  'long',//L，长
            'priuserdefdecm3'       =>  'high',//H，高
            'priuserdefdecm4'       =>  'thickness',//板厚
            'priuserdefdecm6'       =>  'weld',//焊接
            'priuserdefdecm7'       =>  'slot',//刨槽
            'priuserdefdecm8'       =>  'sort',//恒亚序号
        ];

        $DynamicPropertyKeys = [];
        $DynamicPropertyValues = [];
        foreach ($DynamicProperty as $k=>$v){
            $DynamicPropertyKeys[] = $k;
            if(strpos($k,'priuserdefdecm') !== false)$data[$v] = floatval($data[$v]);
            $DynamicPropertyValues[] = $data[$v];
        }
        $params['dto']['DynamicPropertyKeys'] = $DynamicPropertyKeys;
        $params['dto']['DynamicPropertyValues'] = $DynamicPropertyValues;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //物料清单查询
    public static function bomQuery($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/bom/Query";

        $params = [
            'dto'                       =>  [
                'Code'              =>  $data['archives_sn'],//编号
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //物料清单创建
    public static function bomCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/bom/Create";

        $params = [
            'dto'                       =>  [
                'Inventory'             =>  [
                    'Code'              =>  $data['archives_sn'],//编号
                    //'Name'              =>  $data['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//计量单位
                ],
                'Version'               =>  '组装拆卸',//版本号
                'ProduceQuantity'       =>  $data['row_area'],//生产数量
                'YieldRate'             =>  1,//成品率
                'BOMChildDTOs'          =>  [],//子件明细
            ]
        ];

        $BOMChildDTOs = [];
        foreach ($data['lists'] as $v){
            $BOMChildDTOs[] = [
                'Inventory'             =>  [
                    'Code'              =>  self::getInvertoryCode($v),//编号
                    //'Name'              =>  $v['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//子件计量单位
                ],
                'Unit2'                 =>  [
                    'Name'              =>  '件'//计量单位2
                ],
                'RequiredQuantity'       =>  $v['row_area'],//生产数量
            ];
        }
        $params['dto']['BOMChildDTOs'] = $BOMChildDTOs;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //物料清单审核
    public static function bomAudit($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/bom/Audit";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['archives_sn'],//编号
                'Version'               =>  '组装拆卸',//版本号
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //销售订单查询
    public static function saleOrderQuery($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/SaleOrderOpenApi/GetVoucherDTO";

        $params = [
            'param'                     =>  [
                //'voucherID'             =>  $data['tcloud_sale_order_id'],//单据ID
                'externalCode'          =>  $data['archives_sn'],//编号
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //销售订单创建
    public static function saleOrderCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/SaleOrderOpenApi/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['archives_sn'],//编号
                'ExternalCode'          =>  $data['archives_sn'],//外部系统单据编码
                'Customer'              =>  [//客户
                    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                ],
                //'SettleCustomer'        =>  [//结算客户
                //    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                //],
                'Project'               =>  [
                    'Code'              =>  $data['order_sn'],//项目编码，（T+的项目编码，可通过接口查询）
                ],
                'Clerk'                 =>  [
                    'Code'              =>  $data['sales_code'],//业务员编码，（T+的业务员编码，可通过接口查询）
                ],
                'Department'            =>  [
                    'Code'              =>  '0401',//部门编码 0401：装饰销售（T+的部门编码，去销售订单那里查看）
                ],
                'SaleOrderDetails'      =>  [],//子件明细
            ]
        ];

        $SaleOrderDetails = [];
        foreach ($data['lists'] as $v){
            $SaleOrderDetails[] = [
                'Inventory'             =>  [
                    'Code'              =>  self::getInvertoryCode($v),//编号
                    //'Name'              =>  $v['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//子件计量单位
                ],
                'OrigDiscountPrice'     =>  0,//单价
                //'TaxRate'               =>  0,//税率
                'Quantity2'             =>  $v['number'],//生产数量2
            ];
        }
        $params['dto']['SaleOrderDetails'] = $SaleOrderDetails;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //销售出库单创建
    public static function saleDispatchCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/saleDispatch/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['archives_sn'],//编号
                'ExternalCode'          =>  $data['archives_sn'],//外部系统单据编码
                'Partner'               =>  [//客户
                    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                ],
                //'SettleCustomer'        =>  [//结算客户
                //    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                //],
                'Project'               =>  [
                    'Code'              =>  $data['order_sn'],//项目编码，（T+的项目编码，可通过接口查询）
                ],
                'Clerk'                 =>  [
                    'Code'              =>  $data['sales_code'],//业务员编码，（T+的业务员编码，可通过接口查询）
                ],
                'Department'            =>  [
                    'Code'              =>  '0401',//部门编码 0401：装饰销售（T+的部门编码，去销售订单那里查看）
                ],
                'VoucherType'           =>  [
                    'Code'              =>  'ST1021',//单据类型编码；固定值：ST1021
                ],
                'BusiType'              =>  [
                    'Code'              =>  '15',//业务类型编码；15：普通销售  16：销售退货
                ],
                'Warehouse'             =>  [
                    'Code'              =>  '08',//仓库编码，（去T+系统，存货那里查看）
                ],
                'RDRecordDetails'       =>  [],//子件明细
            ]
        ];

        $RDRecordDetails = [];
        foreach ($data['lists'] as $v){
            $RDRecordDetails[] = [
                'Inventory'             =>  [
                    'Code'              =>  self::getInvertoryCode($v),//编号
                    //'Name'              =>  $v['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//子件计量单位
                ],
                'Price'                 =>  0,//成本单价
                //'BaseQuantity'          =>  $v['row_area'],//主计量单位数量
                'SubQuantity'           =>  $v['row_area'],//主计量单位数量
            ];
        }
        $params['dto']['RDRecordDetails'] = $RDRecordDetails;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //形态转换单查询
    public static function shapeVoucherQuery($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/ShapeVoucherOpenApi/GetVoucherDTO";

        $params = [
            'param'                     =>  [
                //'voucherID'             =>  $data['tcloud_sale_order_id'],//单据ID
                'voucherCode'           =>  $data['archives_sn'],//编号
                //'externalCode'          =>  $data['archives_sn'],//编号
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //形态转换单创建
    public static function shapeVoucherCreate($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/ShapeVoucherOpenApi/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['archives_sn'],//编号
                'ExternalCode'          =>  $data['archives_sn'],//外部系统单据编码
                'IsModifiedCode'        =>  'false',//是否修改编号
                'VoucherDate'           =>  date('Y-m-d'),//日期
                'DispatchStyle'         =>  [
                    'Code'              =>  '205',//出库类别编码  205：转换出库
                ],
                'ReceiveStyle'          =>  [
                    'Code'              =>  '109',//入库类别编码  109：转换入库
                ],
                'VoucherType'           =>  [
                    'Code'              =>  'ST1033',//单据类型编码；固定值：ST1033
                ],
                'BeforeShapeDetails'    =>  [],//转换前明细
                'AfterShapeDetails'     =>  [],//转换后明细
            ]
        ];

        $BeforeShapeDetails = [];//转换前明细，为子件合计
        $AfterShapeDetails = [];//转换后明细，为子件明细

        $count = count($data['lists']);
        $price = $row_area = 0;
        foreach ($data['lists'] as $v){
            //转换后明细
            $AfterShapeDetails[] = [
                'Warehouse'             =>  [
                    'Code'              =>  '08',//默认仓库编码，（去T+系统，存货那里查看）
                    //'Name'              =>  '成品',//默认仓库名称，（去T+系统，存货那里查看）
                ],
                'Inventory'             =>  [
                    'Code'              =>  self::getInvertoryCode($v),//编号
                    //'Name'              =>  $v['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//子件计量单位
                ],
                //'Price'                 =>  $v['price'],//单价
                'Quantity'              =>  $v['row_area'],//数量

            ];
            //$price += $v['price'];
            $row_area += $v['row_area'];
        }
        //转换前明细
        $BeforeShapeDetails[] = [
            'Warehouse'             =>  [
                'Code'              =>  '08',//默认仓库编码，（去T+系统，存货那里查看）
                //'Name'              =>  '成品',//默认仓库名称，（去T+系统，存货那里查看）
            ],
            'Inventory'             =>  [
                'Code'              =>  $data['archives_sn'],//编号
                //'Name'              =>  $v['archives_sn'],//名称
            ],
            'Unit'                  =>  [
                'Name'              =>  '㎡'//子件计量单位
            ],
            //'Price'                 =>  round(($price/$count),2),//单价
            'Quantity'              =>  round(($row_area/$count),2),//数量

        ];

        $params['dto']['BeforeShapeDetails'] = $BeforeShapeDetails;
        $params['dto']['AfterShapeDetails'] = $AfterShapeDetails;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //销货单查询
    public static function saleDeliveryQuery($data)
    {
        $config = self::$config;
        $api = $config['url']."/tplus/api/v2/SaleDeliveryOpenApi/GetVoucherDTO";

        $params = [
            'param'                       =>  [
                //'Code'                  =>  $data['address_sn'],//编号
                'externalCode'            =>  $data['address_sn'],//编号
            ]
        ];

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }

    //销货单创建（关联销售订单）
    public static function saleDeliveryCreate($data)
    {
        $config = self::$config;
        //关联销售订单
        //$api = $config['url']."/tplus/api/v2/SaleDeliveryOpenApi/Create";
        //不关联销售订单
        $api = $config['url']."/tplus/api/v2/saleDelivery/Create";

        $params = [
            'dto'                       =>  [
                'Code'                  =>  $data['address_sn'],//编号
                'ExternalCode'          =>  $data['address_sn'],//外部系统单据编码
                //'IsModifiedCode'        =>  'false',//是否修改编号
                'Customer'              =>  [//客户
                    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                ],
                //'SettleCustomer'        =>  [//结算客户
                //    'Code'              =>  $data['company_code'],//来往单位编码，（T+的来往单位编码，可通过接口查询）
                //],
                'Project'               =>  [
                    'Code'              =>  $data['order_sn'],//项目编码，（T+的项目编码，可通过接口查询）
                ],
                'Clerk'                 =>  [
                    'Code'              =>  $data['sales_code'],//业务员编码，（T+的业务员编码，可通过接口查询）
                ],
                'Department'            =>  [
                    'Code'              =>  '0401',//部门编码 0401：装饰销售（T+的部门编码，去销售订单那里查看）
                ],
                'VoucherType'           =>  [
                    'Code'              =>  'ST1021',//单据类型编码；固定值：ST1021
                ],
                'BusiType'              =>  [
                    'Code'              =>  '15',//业务类型编码；15：普通销售  16：销售退货
                ],
                'Warehouse'             =>  [
                    'Code'              =>  '08',//仓库编码，（去T+系统，存货那里查看）
                ],
                'SaleDeliveryDetails'   =>  [],//子件明细
            ]
        ];

        $SaleDeliveryDetails = [];
        foreach ($data['lists'] as $v){
            //销售订单的子件明细ID（T+的销售订单的子件明细ID，通过接口查询）
            $sale_order_details_id = isset($data['sale_order_details_list'][self::getInvertoryCode($v)])?$data['sale_order_details_list'][self::getInvertoryCode($v)]:'';
            $SaleDeliveryDetails[] = [
                'Inventory'             =>  [
                    'Code'              =>  self::getInvertoryCode($v),//编号
                    //'Name'              =>  $v['archives_sn'],//名称
                ],
                'Unit'                  =>  [
                    'Name'              =>  '㎡'//子件计量单位
                ],
                'OrigTaxPrice'          =>  $v['price'],//含税单价（关联销售订单时不支持设置）
                //'TaxRate'               =>  0,//税率（关联销售订单时不支持设置）
                'Quantity'              =>  $v['row_area'],//数量

                //------------------关联销售订单---------------
                //'idsourcevouchertype'   =>  '43',//来源单据类型ID  销售订单：43  销货单：104  销售出库单：19
                //'sourceVoucherCode'     =>  $data['archives_sn'],//来源单据编码
                //'sourceVoucherDetailId' =>  $sale_order_details_id,//销售订单的子件明细ID（T+的销售订单的子件明细ID，通过接口查询）
            ];
        }
        $params['dto']['SaleDeliveryDetails'] = $SaleDeliveryDetails;

        $resp = self::async($api, $params);
        //返回地址信息 如果status!=0则信息错误
        return json_decode($resp, true);
    }
}
